package com.keepers.repair.mina;

import com.keepers.repair.net.LogUtil;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.net.InetSocketAddress;

/**
 * auth aboom
 * date 2018/12/11
 */
public class ConnectionManager {

    private NioSocketConnector connector;
    private Thread             connectThread;
    private ConnectionConfig   config;

    public ConnectionManager(ConnectionConfig config) {
        this.config = config;
    }

    /**
     * 与服务器连接
     */
    public void connect() {
        if (connectThread != null) {
            return;
        }
        connectThread = new Thread(() -> {
            for (; ; ) {
                InetSocketAddress inetSocketAddress = new InetSocketAddress(config.getIp(), config.getPort());
                connector = new NioSocketConnector();
                connector.setConnectTimeoutMillis(10 * 1000);
                connector.getFilterChain().addLast("logger", new LoggingFilter());
                //设置读数据大小
                connector.getSessionConfig().setReadBufferSize(config.getReadBufferSize());
                //编码过滤
                connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                        new ObjectSerializationCodecFactory()));
                //事物处理
                connector.setHandler(new IoHandlerAdapter() {
                    @Override
                    public void sessionCreated(IoSession ioSession) throws Exception {
                        super.sessionCreated(ioSession);
                        LogUtil.e("sessionCreated");

                    }

                    @Override
                    public void sessionOpened(IoSession ioSession) throws Exception {
                        super.sessionOpened(ioSession);
                        LogUtil.e("连接打开");
                    }

                    @Override
                    public void sessionClosed(IoSession ioSession) throws Exception {
                        super.sessionClosed(ioSession);
                        LogUtil.e("连接关闭，每隔5秒进行重新连接");

                    }

                    @Override
                    public void sessionIdle(IoSession ioSession, IdleStatus idleStatus) throws Exception {
                        super.sessionIdle(ioSession, idleStatus);
                        LogUtil.e("客户端与服务端连接空闲");
                    }

                    @Override
                    public void exceptionCaught(IoSession ioSession, Throwable throwable) throws Exception {
                        super.exceptionCaught(ioSession, throwable);
                        LogUtil.e("exceptionCaught");

                    }

                    @Override
                    public void messageReceived(IoSession ioSession, Object o) throws Exception {
                        super.messageReceived(ioSession, o);
                        LogUtil.e("收到数据，接下来你要怎么解析数据就是你的事了");
                    }

                    @Override
                    public void messageSent(IoSession ioSession, Object o) throws Exception {
                        super.messageSent(ioSession, o);

                        LogUtil.e("messageSent");

                    }

                    @Override
                    public void inputClosed(IoSession ioSession) throws Exception {
                        super.inputClosed(ioSession);
                        LogUtil.e("inputClosed");


                    }
                });
                connector.setDefaultRemoteAddress(inetSocketAddress);
                ConnectFuture future = connector.connect();
                future.awaitUninterruptibly();
                IoSession session = future.getSession();
                if (session != null && session.isConnected()) {
                    SessionManager.getInstance().setSession(session);
                    break;
                }
                try {
                    LogUtil.e("尝试重新连接");
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            connectThread = null;
        });
        connectThread.start();
    }
}
